//-------------------------------------------
// game.h
//-------------------------------------------

/**
 * @file game.h
 * Contains the class that has the information about the game.
 *
 * @see logic::CGame
 */

#pragma once

#include <vector>
#include <list>
#include <string>
#include "logicfacade.h"

namespace logic {

	class CEntity;

	class CGame : public ILogicFacade {

	public:

		CGame();
		~CGame();

	protected:

		enum TEventId {

			EDEAD,

		}; // enum TEventId

		struct TEvent {

			TEventId id;
			explicit TEvent(TEventId eid) : id(eid) {}

		}; // struct TEvent

		std::list<CEntity*> entities;		// Game logic entities
		//CPlayer *player1;					// Direct access to the player
		//CPlayer *player2;					// We frecuently need to access the player
		std::vector<TCommand> commandQueue;	// Input command queue
		std::vector<TEvent> eventQueue;		// Game event queue

		// Tells if we are in the middle of a game (if init has been called)
		// Most of the class methods will fail if we are not in the middle of a game.
		bool playing;

		/**********************************/
		/*		APPLICATION METHODS       */
		/**********************************/

		// Init the game with all the needed entities
		// We'll usually want to register at least a creation/destruction observer before
		bool init();

		// End the game, destroying all the created logic entities
		void end();

		/**
		 * Logic update tick for the whole game. In each step:
		 *
		 *	- Process the logic input command queue
		 *	- Update all the entities
		 *	- Process the game event queue
		 */
		void update();

		// Insert a new command in the command queue. Processed in the next update() call
		void insertCommand(TCommand command);

		// Add a player events observer
		//bool addObserver(CPlayer::Observer* newObserver);

		// Remove a player events observer
		//bool removeObserver(CPlayer::Observer* oldObserver);

		/********************************************************************/
		/*		METHODS FOR EVENT INSERTION FROM THE REST OF THE LOGIC      */
		/********************************************************************/

		// Function to access the game player. Use with caution, it gives access, from the
		// outside to the player position. The IA could cheat through this method.
		//CPlayer *getPlayer(int i = 1) const
		//{
		//	if (i == 1)
		//		return player1;
		//	else
		//		return player2;
		//}

	protected:

		// Clean all the message and event queues between frames. It must be invoked
		// at the end of the game tick
		void clean();

		// Process the command queue and invoke the corresponding player method
		void processCommandQueue();

		// Process the event queue and update the game logic accordingly
		void processEventQueue();

	}; // class ILogicFacade


} // namespace logic